<template>
  <div class="admin-container">
    <!-- 页面标题与操作区 -->
    <div class="page-header">
      <h2>管理员-工人管理</h2>
      <div class="operation-btns">
        <button class="btn primary" @click="openAddDialog">新增工人</button>
        <button
          class="btn danger"
          @click="batchDeleteWorkers"
          :disabled="selectedPhones.length === 0"
        >
          批量删除
        </button>
        <button class="btn warning" @click="openBatchAddDialog">
          批量新增
        </button>
      </div>
    </div>

    <!-- 搜索区 -->
    <div class="search-bar">
      <input
        type="text"
        v-model="searchPhone"
        placeholder="输入手机号搜索"
        class="search-input"
      />
      <button class="btn primary" @click="fetchWorkerList">搜索</button>
      <button class="btn default" @click="resetSearch">重置</button>
    </div>

    <!-- 工人列表 -->
    <div class="table-container">
      <table class="data-table">
        <thead>
          <tr>
            <th class="select-col">
              <input
                type="checkbox"
                @change="selectAll"
                v-model="allSelected"
              />
            </th>
            <th>用户名</th>
            <th>手机号</th>
            <th>邮箱</th>
            <th>状态</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="worker in workerList" :key="worker.userId">
            <td>
              <input
                type="checkbox"
                v-model="selectedPhones"
                :value="worker.phone"
                @change="checkAllSelected"
              />
            </td>
            <td>{{ worker.account }}</td>
            <td>{{ worker.phone }}</td>
            <td>{{ worker.email || "-" }}</td>
            <td>
              <span
                class="status-tag"
                :class="worker.status === '0' ? 'banned' : 'active'"
              >
                {{ worker.status === "0" ? "封禁" : "正常" }}
              </span>
            </td>
            <td class="operation-col">
              <button
                class="btn text primary"
                @click="resetWorkerPassword(worker.phone)"
              >
                重置密码
              </button>
              <button
                class="btn text"
                :class="worker.status === '0' ? 'success' : 'danger'"
                @click="handleStatusChange(worker)"
              >
                {{ worker.status === "0" ? "解封" : "封禁" }}
              </button>
            </td>
          </tr>
          <tr v-if="workerList.length === 0">
            <td colspan="6" class="empty-state">暂无数据</td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- 分页 -->
    <div class="pagination" v-if="total > 0">
      <span class="total">共 {{ total }} 条记录</span>
      <button
        class="btn default"
        @click="changePage(pageNum - 1)"
        :disabled="pageNum <= 1"
      >
        上一页
      </button>
      <span class="page-info">第 {{ pageNum }} / {{ totalPages }} 页</span>
      <button
        class="btn default"
        @click="changePage(pageNum + 1)"
        :disabled="pageNum >= totalPages"
      >
        下一页
      </button>
    </div>

    <!-- 新增工人弹窗 -->
    <div class="modal-mask" v-if="addDialogVisible">
      <div class="modal">
        <div class="modal-header">
          <h3>新增工人</h3>
          <button class="close-btn" @click="addDialogVisible = false">
            &times;
          </button>
        </div>
        <div class="modal-body">
          <form @submit.prevent="submitAddForm" class="modal-form">
            <div class="form-group">
              <label>用户名</label>
              <input
                type="text"
                v-model="addForm.account"
                @input="validateAccount(addForm.account, 'add')"
                @blur="validateAccount(addForm.account, 'add')"
              />
              <p v-if="addErrors.account" class="error-message">
                {{ addErrors.account }}
              </p>
            </div>
            <div class="form-group">
              <label>手机号</label>
              <input
                type="tel"
                v-model="addForm.phone"
                @input="validatePhone(addForm.phone, 'add')"
                @blur="validatePhone(addForm.phone, 'add')"
              />
              <p v-if="addErrors.phone" class="error-message">
                {{ addErrors.phone }}
              </p>
            </div>
            <div class="form-group">
              <label>密码</label>
              <input
                type="password"
                v-model="addForm.password"
                @input="validatePassword(addForm.password)"
                @blur="validatePassword(addForm.password)"
                autocomplete="new-password"
              />
              <p v-if="addErrors.password" class="error-message">
                {{ addErrors.password }}
              </p>
            </div>
            <div class="form-actions">
              <button
                type="button"
                class="btn default"
                @click="addDialogVisible = false"
              >
                取消
              </button>
              <button
                type="submit"
                class="btn primary"
                :disabled="!isAddFormValid"
              >
                确定
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <!-- 批量新增弹窗 -->
    <div class="modal-mask" v-if="batchAddDialogVisible">
      <div class="modal">
        <div class="modal-header">
          <h3>批量新增工人</h3>
          <button class="close-btn" @click="batchAddDialogVisible = false">
            &times;
          </button>
        </div>
        <div class="modal-body">
          <form @submit.prevent="submitBatchAddForm" class="modal-form">
            <div class="form-group">
              <label>手机号列表（每行一个）</label>
              <textarea
                v-model="batchAddForm.phoneList"
                rows="6"
                @input="validateBatchPhones"
                @blur="validateBatchPhones"
              ></textarea>
              <p v-if="batchAddError" class="error-message">
                {{ batchAddError }}
              </p>
            </div>
            <div class="form-actions">
              <button
                type="button"
                class="btn default"
                @click="batchAddDialogVisible = false"
              >
                取消
              </button>
              <button
                type="submit"
                class="btn primary"
                :disabled="!!batchAddError"
              >
                确定
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <!-- 编辑工人弹窗 -->
    <div class="modal-mask" v-if="editDialogVisible">
      <div class="modal">
        <div class="modal-header">
          <h3>编辑工人</h3>
          <button class="close-btn" @click="editDialogVisible = false">
            &times;
          </button>
        </div>
        <div class="modal-body">
          <form @submit.prevent="submitEditForm" class="modal-form">
            <div class="form-group">
              <label>用户名</label>
              <input
                type="text"
                v-model="editForm.account"
                @input="validateAccount(editForm.account, 'edit')"
                @blur="validateAccount(editForm.account, 'edit')"
              />
              <p v-if="editErrors.account" class="error-message">
                {{ editErrors.account }}
              </p>
            </div>
            <div class="form-group">
              <label>手机号</label>
              <input
                type="tel"
                v-model="editForm.phone"
                @input="validatePhone(editForm.phone, 'edit')"
                @blur="validatePhone(editForm.phone, 'edit')"
              />
              <p v-if="editErrors.phone" class="error-message">
                {{ editErrors.phone }}
              </p>
            </div>
            <div class="form-group">
              <label>邮箱（可选）</label>
              <input type="email" v-model="editForm.email" />
            </div>
            <div class="form-actions">
              <button
                type="button"
                class="btn default"
                @click="editDialogVisible = false"
              >
                取消
              </button>
              <button
                type="submit"
                class="btn primary"
                :disabled="!isEditFormValid"
              >
                确定
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>

    <!-- 提示消息 -->
    <div class="toast" v-if="toastMessage">{{ toastMessage }}</div>
  </div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from "vue";
import axios from "axios";
import { inMemoryStorage } from "/src/router/index.js";
import { useRouter } from "vue-router";

// 初始化路由实例
const router = useRouter();

// axios 核心配置
axios.defaults.baseURL = "http://localhost:8080";
axios.defaults.withCredentials = true;
axios.defaults.headers.common["Accept"] = "application/json";
axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";

// 请求拦截器
axios.interceptors.request.use(
  (config) => {
    const token = inMemoryStorage.token || "";
    if (token) {
      config.headers["Authorization"] = `Bearer ${token}`;
    }
    if (!token && !config.url.includes("/login")) {
      router.replace("/");
      showToast("请先登录");
      return Promise.reject(new Error("未登录"));
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器
axios.interceptors.response.use(
  (response) => {
    if (typeof response.data === "string") {
      showToast(response.data);
    }
    return response;
  },
  (error) => {
    if (error.response) {
      const status = error.response.status;
      const message = error.response.data || "操作失败";
      showToast(`[${status}] ${message}`);
      if (status === 401) {
        inMemoryStorage.token = null;
        router.replace("/");
        showToast("登录已失效，请重新登录");
      }
    } else if (error.request) {
      showToast("无法连接服务器，请检查后端是否启动");
    } else {
      showToast("请求异常：" + error.message);
    }
    return Promise.reject(error);
  }
);

// 分页参数
const pageNum = ref(1);
const pageSize = ref(10);
const total = ref(0);
const totalPages = computed(() => Math.ceil(total.value / pageSize.value) || 1);

// 数据列表（存储所有工人，用于前端过滤）
const allWorkers = ref([]);
// 展示列表（过滤后的结果）
const workerList = ref([]);
// 搜索参数
const searchPhone = ref("");

// 选择相关
const selectedPhones = ref([]);
const allSelected = ref(false);

// 弹窗控制
const addDialogVisible = ref(false);
const batchAddDialogVisible = ref(false);
const editDialogVisible = ref(false);

// 表单数据
const addForm = reactive({
  account: "",
  phone: "",
  password: "",
});

const batchAddForm = reactive({
  phoneList: "",
});

const editForm = reactive({
  userId: "",
  account: "",
  phone: "",
  email: "",
});

// 错误信息
const addErrors = reactive({
  account: "",
  phone: "",
  password: "",
});

const editErrors = reactive({
  account: "",
  phone: "",
});

const batchAddError = ref("");
const toastMessage = ref("");

// 表单验证状态
const isAddFormValid = computed(() => {
  return (
    !addErrors.account &&
    !addErrors.phone &&
    !addErrors.password &&
    addForm.account.trim() &&
    addForm.phone.trim() &&
    addForm.password.trim()
  );
});

const isEditFormValid = computed(() => {
  return (
    !editErrors.account &&
    !editErrors.phone &&
    editForm.account.trim() &&
    editForm.phone.trim()
  );
});

// 加载当前页工人列表
const fetchAllWorkers = async () => {
  try {
    const response = await axios.post(
      "/user/admin/workerSelect",
      {},
      { params: { pageNum: pageNum.value } }
    );

    if (response.data.message === "查询成功") {
      allWorkers.value = response.data.list || [];
      total.value = response.data.total || 0;
      pageSize.value = response.data.pageSize || 10;
      filterWorkersByPhone(); // 触发过滤
    } else {
      showToast("获取数据失败：" + (response.data.message || "未知错误"));
    }
  } catch (error) {
    console.error("获取工人列表失败:", error);
    if (error.message.includes("401")) {
      showToast("权限不足或登录已失效，请重新登录");
      inMemoryStorage.token = null;
      router.replace("/");
    } else {
      showToast("网络错误，无法获取数据");
    }
  }
};

// 前端按手机号过滤
const filterWorkersByPhone = () => {
  const phoneStr = searchPhone.value.trim();
  if (!phoneStr) {
    // 无搜索条件：显示当前页所有工人
    workerList.value = [...allWorkers.value];
    return;
  }

  // 有搜索条件：精确匹配手机号
  const filtered = allWorkers.value.filter(
    (worker) => worker.phone === phoneStr
  );

  workerList.value = filtered;
  total.value = filtered.length; // 更新总条数为过滤后数量
};

// 搜索触发
const fetchWorkerList = async () => {
  const phoneStr = searchPhone.value.trim();
  // 搜索时强制查第一页，避免分页数据不全
  if (phoneStr) {
    pageNum.value = 1;
  }
  await fetchAllWorkers();
};

// 页面加载时初始化
onMounted(() => {
  fetchWorkerList();
});

// 提示消息
const showToast = (message) => {
  toastMessage.value = message;
  setTimeout(() => {
    toastMessage.value = "";
  }, 3000);
};

// 分页切换
const changePage = (num) => {
  // 搜索状态下禁用分页
  if (searchPhone.value.trim()) return;

  if (num >= 1 && num <= totalPages.value) {
    pageNum.value = num;
    fetchWorkerList();
  }
};

// 全选/取消全选
const selectAll = () => {
  if (allSelected.value) {
    selectedPhones.value = workerList.value.map((worker) => worker.phone);
  } else {
    selectedPhones.value = [];
  }
};

// 检查全选状态
const checkAllSelected = () => {
  allSelected.value =
    workerList.value.length > 0 &&
    selectedPhones.value.length === workerList.value.length;
};

// 重置搜索
const resetSearch = () => {
  searchPhone.value = "";
  pageNum.value = 1;
  fetchWorkerList();
};

// 验证用户名
const validateAccount = (value, type) => {
  const errors = type === "add" ? addErrors : editErrors;
  if (!value.trim()) {
    errors.account = "用户名不能为空";
  } else if (!/^[\u4e00-\u9fa5A-Za-z0-9._-]{1,20}$/.test(value)) {
    errors.account = "只能包含中文、英文、数字及 . - _";
  } else {
    errors.account = "";
  }
};

// 验证手机号
const validatePhone = (value, type) => {
  const errors = type === "add" ? addErrors : editErrors;
  const phoneStr = value.trim();
  if (!phoneStr) {
    errors.phone = "手机号不能为空";
  } else if (!/^\d{11}$/.test(phoneStr)) {
    errors.phone = "请输入11位数字的手机号";
  } else {
    errors.phone = "";
  }
};

// 验证密码
const validatePassword = (value) => {
  if (!value.trim()) {
    addErrors.password = "密码不能为空";
  } else if (
    !/^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d!@#$%^&*()_+]{8,20}$/.test(value)
  ) {
    addErrors.password = "8-20位，至少包含字母和数字";
  } else {
    addErrors.password = "";
  }
};

// 验证批量手机号
const validateBatchPhones = () => {
  if (!batchAddForm.phoneList.trim()) {
    batchAddError.value = "手机号列表不能为空";
    return;
  }

  const phones = batchAddForm.phoneList
    .split("\n")
    .map((phone) => phone.trim())
    .filter((phone) => phone);

  const uniquePhones = [...new Set(phones)];
  if (uniquePhones.length !== phones.length) {
    batchAddError.value = "手机号列表存在重复，请去除重复号码";
    return;
  }

  for (const phone of uniquePhones) {
    if (!/^\d{11}$/.test(phone)) {
      batchAddError.value = `手机号 ${phone} 格式不正确（需11位数字）`;
      return;
    }
  }

  batchAddError.value = "";
};

// 打开新增弹窗
const openAddDialog = () => {
  addForm.account = "";
  addForm.phone = "";
  addForm.password = "";
  Object.keys(addErrors).forEach((key) => (addErrors[key] = ""));
  addDialogVisible.value = true;
};

// 提交新增表单
const submitAddForm = async () => {
  try {
    const payload = {
      ...addForm,
      phone: addForm.phone.trim(),
    };
    await axios.post("/user/admin/workerRegister", payload);
    addDialogVisible.value = false;
    await fetchWorkerList();
  } catch (error) {
    console.error("新增失败:", error);
    showToast("新增失败，请重试");
  }
};

// 打开批量新增弹窗
const openBatchAddDialog = () => {
  batchAddForm.phoneList = "";
  batchAddError.value = "";
  batchAddDialogVisible.value = true;
};

// 提交批量新增表单
const submitBatchAddForm = async () => {
  try {
    const phones = batchAddForm.phoneList
      .split("\n")
      .map((phone) => phone.trim())
      .filter((phone) => phone);

    const response = await axios.post(
      "/user/admin/workerBatchRegister",
      phones
    );
    showToast(response.data);
    batchAddDialogVisible.value = false;
    await fetchWorkerList();
  } catch (error) {
    console.error("批量新增失败:", error);
    showToast("批量新增失败，请重试");
  }
};

// 批量删除
const batchDeleteWorkers = async () => {
  if (!confirm("确定要删除选中的工人吗？删除后不可恢复！")) return;
  if (selectedPhones.value.length === 0) {
    showToast("请选择要删除的工人");
    return;
  }

  try {
    const response = await axios.post(
      "/user/admin/workerDelete",
      selectedPhones.value
    );
    showToast(response.data);
    selectedPhones.value = [];
    allSelected.value = false;
    await fetchWorkerList();
  } catch (error) {
    console.error("批量删除失败:", error);
    showToast("批量删除失败，请重试");
  }
};

// 重置密码
const resetWorkerPassword = async (phone) => {
  if (!confirm("确定要重置该工人密码吗？默认密码为 123456abc")) return;

  try {
    const response = await axios.post(
      "/user/admin/passwordReset",
      {},
      { params: { phone } }
    );
    showToast(response.data);
  } catch (error) {
    console.error("重置密码失败:", error);
    showToast("重置密码失败，请重试");
  }
};

// 处理封禁/解封
const handleStatusChange = async (worker) => {
  const isBanned = worker.status === "0";
  const actionText = isBanned ? "解封" : "封禁";
  const apiUrl = isBanned ? "/user/admin/statusUnban" : "/user/admin/statusBan";

  if (!confirm(`确定要${actionText}该工人吗？`)) return;

  try {
    await axios.post(apiUrl, {}, { params: { phone: worker.phone } });
    showToast(`${actionText}成功`);
    await fetchWorkerList();
    workerList.value = [...workerList.value];
  } catch (error) {
    console.error(`${actionText}失败：`, error);
    showToast(`${actionText}失败，请重试`);
  }
};
</script>
<style scoped>
.admin-container {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}

.operation-btns {
  display: flex;
  gap: 10px;
}

.search-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  align-items: center;
}

.search-input {
  flex: 0 0 300px;
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.table-container {
  overflow-x: auto;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid #eee;
}

.data-table th,
.data-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #eee;
}

.data-table th {
  background-color: #f9f9f9;
  font-weight: 600;
}

.select-col {
  width: 50px;
}

.operation-col {
  display: flex;
  gap: 10px;
}

.status-tag {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
}

/* 封禁状态（红色背景+文字） */
.status-tag.banned {
  background-color: #fde2e2;
  color: #f5222d;
}

/* 正常状态（绿色背景+文字） */
.status-tag.active {
  background-color: #e1f3d8;
  color: #52c41a;
}

.empty-state {
  text-align: center;
  padding: 40px;
  color: #999;
}

.pagination {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 20px;
  justify-content: flex-end;
}

.total {
  color: #666;
}

.modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background-color: white;
  border-radius: 6px;
  width: 100%;
  max-width: 500px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.modal-header {
  padding: 15px 20px;
  border-bottom: 1px solid #eee;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-body {
  padding: 20px;
}

.modal-form {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.form-group label {
  font-weight: 500;
  color: #333;
}

.form-group input,
.form-group textarea {
  padding: 8px 12px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}

.form-group textarea {
  resize: vertical;
}

.form-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 10px;
}

.close-btn {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  color: #999;
}

.close-btn:hover {
  color: #333;
}

.error-message {
  color: #f5222d;
  font-size: 12px;
  margin: 0;
}

.toast {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px 20px;
  border-radius: 4px;
  z-index: 1001;
  animation: fadein 0.3s, fadeout 0.3s 2.7s;
}

/* 按钮样式 */
.btn {
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
}

.btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.btn.primary {
  background-color: #409eff;
  color: white;
}

.btn.primary:hover:not(:disabled) {
  background-color: #66b1ff;
}

.btn.danger {
  background-color: #f5222d;
  color: white;
}

.btn.danger:hover:not(:disabled) {
  background-color: #ff4d4f;
}

.btn.warning {
  background-color: #faad14;
  color: white;
}

.btn.warning:hover:not(:disabled) {
  background-color: #ffc53d;
}

.btn.default {
  background-color: #f5f5f5;
  color: #333;
}

.btn.default:hover:not(:disabled) {
  background-color: #e8e8e8;
}

.btn.text {
  background: none;
  color: #666;
  padding: 4px 8px;
}

.btn.text:hover {
  color: #409eff;
}

.btn.text.primary {
  color: #409eff;
}

.btn.text.danger {
  color: #f5222d;
}

.btn.text.success {
  color: #52c41a;
}

/* 动画效果 */
@keyframes fadein {
  from {
    top: 0;
    opacity: 0;
  }
  to {
    top: 20px;
    opacity: 1;
  }
}

@keyframes fadeout {
  from {
    top: 20px;
    opacity: 1;
  }
  to {
    top: 0;
    opacity: 0;
  }
}

/* 适配小屏幕 */
@media (max-width: 768px) {
  .admin-container {
    padding: 10px;
  }

  .search-input {
    flex: 1;
  }

  .operation-col {
    flex-direction: column;
    gap: 5px;
  }

  .modal {
    width: 90%;
  }
}
</style>
